package com.piggy.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONUtil;
import com.piggy.common.core.annotation.RepeatSubmit;
import com.piggy.common.core.constant.Constants;
import com.piggy.common.core.constant.OssConstans;
import com.piggy.common.core.constant.UserConstants;
import com.piggy.common.core.exception.base.BaseException;
import com.piggy.common.core.utils.file.FileUtils;
import com.piggy.common.core.utils.poi.ExcelUtil;
import com.piggy.common.core.utils.sms.SmsConfig;
import com.piggy.common.core.web.controller.BaseController;
import com.piggy.common.core.web.domain.AjaxResult;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.common.log.annotation.Log;
import com.piggy.common.log.enums.BusinessType;
import com.piggy.common.satoken.annotation.Inner;
import com.piggy.oss.cloud.CloudStorageConfig;
import com.piggy.oss.cloud.OSSFactory;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.system.api.bo.OssFileUploadBo;
import com.piggy.common.core.domain.R;
import com.piggy.system.api.domain.SysConfig;
import com.piggy.system.api.domain.SysOss;
import com.piggy.system.domain.bo.SysOssAddBo;
import com.piggy.system.domain.bo.SysOssEditBo;
import com.piggy.system.domain.bo.SysOssQueryBo;
import com.piggy.system.domain.vo.SysOssVo;
import com.piggy.system.service.ISysConfigService;
import com.piggy.system.service.ISysOssService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;

/**
 * 文件上传Controller
 *
 * @author piggy
 * @date 2021-07-20
 */
@Api(value = "文件上传控制器", tags = {"文件上传管理"})
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
@RequestMapping("/oss")
public class SysOssController extends BaseController {

	private final ISysOssService iSysOssService;

	private final ISysConfigService iSysConfigService;

    /**m
     * 查询文件上传列表
     */
    @ApiOperation("查询文件上传列表")
    @SaCheckPermission("oss:oss:list")
    @GetMapping("/list")
    public TableDataInfo<SysOssVo> list(@Validated SysOssQueryBo bo, HttpServletResponse response) {
		response.addHeader("Content-Disposition","inline;filename=piggy");
        return iSysOssService.queryPageList(bo);
    }

    /**
     * 导出文件上传列表
     */
    @SneakyThrows
	@ApiOperation("导出文件上传列表")
    @SaCheckPermission("oss:oss:export")
    @Log(title = "文件上传", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public void export(HttpServletResponse response,@Validated SysOssQueryBo bo) {
        List<SysOssVo> list = iSysOssService.queryList(bo);
        ExcelUtil<SysOssVo> util = new ExcelUtil<SysOssVo>(SysOssVo.class);
         util.exportExcel(response,list, "文件上传");
    }

	/**
	 * 获取消息详细信息
	 */
	@ApiOperation("获取短信配置")
	@SaCheckPermission("incar:oss:config")
	@GetMapping("/config")
	public AjaxResult getConfig() {
		return AjaxResult.success(iSysConfigService.selectConfigByKey(OssConstans.CONTRACT_CLOUDCONFIG));
	}

	/**
	 * 获取消息详细信息
	 */
	@ApiOperation("修改oss配置")
	@SaCheckPermission("incar:oss:config")
	@RepeatSubmit
	@PutMapping("/updateConfig")
	public AjaxResult updateConfig(@Validated @RequestBody CloudStorageConfig config)
	{
		SysConfig sysConfig = iSysConfigService.getConfigByKey(OssConstans.CONTRACT_CLOUDCONFIG);
		if (UserConstants.NOT_UNIQUE.equals(iSysConfigService.checkConfigKeyUnique(sysConfig)))
		{
			return AjaxResult.error("修改参数'" + sysConfig.getConfigName() + "'失败，参数键名已存在");
		}
		sysConfig.setConfigValue(JSONUtil.toJsonStr(config));
		sysConfig.setUpdateBy(SecurityUtils.getUsername());
		return toAjax(iSysConfigService.updateConfig(sysConfig));
	}

	/**
	 * 获取消息详细信息
	 */
	@ApiOperation("修改短信配置")
	@SaCheckPermission("incar:msg:config")
	@RepeatSubmit
	@PutMapping("/updateMsgConfig")
	public AjaxResult updateMsgConfig(@Validated @RequestBody SmsConfig config)
	{
		SysConfig sysConfig = iSysConfigService.getConfigByKey(Constants.ALICLOUDSMS);
		if (UserConstants.NOT_UNIQUE.equals(iSysConfigService.checkConfigKeyUnique(sysConfig)))
		{
			return AjaxResult.error("修改参数'" + sysConfig.getConfigName() + "'失败，参数键名已存在");
		}
		sysConfig.setConfigValue(JSONUtil.toJsonStr(config));
		sysConfig.setUpdateBy(SecurityUtils.getUsername());
		return toAjax(iSysConfigService.updateConfig(sysConfig));
	}
    /**
     * 获取文件上传详细信息
     */
    @ApiOperation("获取文件上传详细信息")
    @SaCheckPermission("oss:oss:query")
    @GetMapping("/{id}")
    public AjaxResult getInfo(@NotNull(message = "主键不能为空")
                                                  @PathVariable("id") Long id) {
        return AjaxResult.success(iSysOssService.queryById(id));
    }

    /**
     * 新增文件上传
     */
    @ApiOperation("新增文件上传")
    @SaCheckPermission("oss:oss:add")
    @Log(title = "文件上传", businessType = BusinessType.INSERT)
    @PostMapping()
    public AjaxResult add(@Validated @RequestBody SysOssAddBo bo) {
        return toAjax(iSysOssService.insertByAddBo(bo) ? 1 : 0);
    }
	/**
	 * 上传文件
	 */
	@PostMapping("/upload")
	@SaCheckPermission("oss:oss:add")
	public AjaxResult add(@RequestParam("file") MultipartFile file) throws Exception {
		if (file.isEmpty()) {
			throw new BaseException("上传文件不能为空");
		}
		SysOss sysOss = iSysOssService.uploadFileToCLoud(file);

		return AjaxResult.success(sysOss.getUrl());
	}
	/**
	 * 上传文件
	 */
	@PostMapping(value = "/uploadFileToCloud", produces = {MediaType.APPLICATION_JSON_VALUE},
			consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
	public SysOss uploadFileToCloud(@RequestPart("file") MultipartFile file) throws Exception {
		if (file.isEmpty()) {
			throw new BaseException("上传文件不能为空");
		}
		return  iSysOssService.uploadFileToCLoud(file);
	}
	/**
	 * 上传文件
	 */
	@PostMapping(value = "/uploadToCloud", produces = {MediaType.APPLICATION_JSON_VALUE},
			consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
	public SysOss uploadToCloud(@RequestBody OssFileUploadBo bo) throws Exception {
		if (bo.getContent()!=null) {
			throw new BaseException("上传文件不能为空");
		}
		return  iSysOssService.uploadToCloud(bo);
	}
    /**
     * 修改文件上传
     */
    @ApiOperation("修改文件上传")
    @SaCheckPermission("oss:oss:edit")
    @Log(title = "文件上传", businessType = BusinessType.UPDATE)
    @PutMapping()
    public AjaxResult edit(@Validated @RequestBody SysOssEditBo bo) {
        return toAjax(iSysOssService.updateByEditBo(bo) ? 1 : 0);
    }
    /**
     * 下载文件
     */
    @SneakyThrows
	@ApiOperation("下载文件")
    @Log(title = "下载文件", businessType = BusinessType.UPDATE)
	@GetMapping("/downloadFile/{id}")
    public void downloadFile(@NotEmpty(message = "主键不能为空")
											 @PathVariable Long id,HttpServletResponse response) {
		SysOss sysOss = iSysOssService.getById(id);
		byte[] bytes = OSSFactory.build().downloadFile(sysOss.getPath());
		FileUtils.setAttachmentResponseHeader(response, sysOss.getName());
		FileUtils.writeBytes(IoUtil.toStream(bytes),response.getOutputStream());
		response.getOutputStream().write(bytes);
	}

	/**
	 * 获取文件url
	 */
	@SneakyThrows
	@ApiOperation("获取文件url")
	@Log(title = "获取文件url", businessType = BusinessType.UPDATE)
	@GetMapping("/getUrl/{id}")
	public AjaxResult getUrl(@NotEmpty(message = "主键不能为空")
							 @PathVariable Long id, HttpServletResponse response) {
		SysOss sysOss = iSysOssService.getById(id);
		SysOssVo sysOssVo = BeanUtil.toBean(sysOss, SysOssVo.class);
		String url = OSSFactory.build().buildUrl(sysOss.getPath());
		sysOssVo.setUrl(url);

		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
		response.setHeader("Access-Control-Max-Age", "3600");
		response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

		return AjaxResult.success(sysOssVo);
	}
    /**
     * 删除文件上传
     */
    @ApiOperation("删除文件上传")
    @SaCheckPermission("oss:oss:remove")
    @Log(title = "文件上传" , businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@NotEmpty(message = "主键不能为空")
                                       @PathVariable Long[] ids) {
        return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
    }

    @Inner
	@GetMapping("/getSysOssVo")
	public AjaxResult getSysOssVo(@RequestParam("id") Long id) {
		return iSysOssService.getSysOssById(id);
	}
}
